/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.hamacekj.dotaznikserver;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

/**
 * Otázka s možnostmi ano/ne.
 * @author Jan Hamáček
 */
public class YNQuestion implements Question {

    public YNQuestion(){
        this.setupContainer();
        this.tableModel.addColumn("Počítač");
        this.tableModel.addColumn("Odpověď");
    }
    
    public YNQuestion(int id, String message) {
        this();
        this.message = message;
        this.id = id;
    }
    
    
    /**
     * Odešle dotaz ano/ne jako textový řetězec po spojení c. Formát textového řetězce je definován interním protokolem.
     * @param c Spojení, po kterém bude dotaz odesílán.
     * @throws IOException Pokud se odesílání nezdařilo
     */
    @Override
    public void send(Connection c) throws IOException {
        c.writeLine("ASK YN "+this.id);
        String[] splitted = this.message.split(System.lineSeparator());
        for(String line: splitted){
            c.writeLine("MSG "+line);
        }
        c.writeLine(".");
    }

    @Override
    public synchronized void addReply(Connection source, String[] reply) {
        try{
            try{
                final Reply rep;
                String[] linearr = reply[0].split(" ");
                if(!"REPLY".equals(linearr[0])){
                    throw new ProtocolException("REPLY type expected");
                }
                if(!"YN".equals(linearr[1])){
                    throw new ProtocolException("YN type expected");
                }
                switch(linearr[3]){
                    case "Y":
                        rep = Reply.Yes;
                        break;
                    case "N":
                        rep = Reply.No;
                        break;
                    default:
                        throw new ProtocolException("Unknown YN reply.");
                }
                
                replies.put(source, rep);
                Object[] row = {source, rep.toString()};
                tableModel.addRow(row);
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        if(Reply.Yes.equals(rep)){
                            yesCounter.inc();
                        }
                        if(Reply.No.equals(rep)){
                            noCounter.inc();
                        }
                    }
                });
                
            }catch(IndexOutOfBoundsException e){
                throw new ProtocolException("Incomplete reply line. Index out of bounds", e);
            }
        }catch(ProtocolException e){
            // TODO: log protocol exception
        }
        
    }

    @Override
    public String getShortDesc() {
        if(this.message != null && !"".equals(this.message)){
            return "A/N: "+this.message;
        }else{
            return "A/N: "+ date.get(Calendar.HOUR_OF_DAY)+":"+date.get(Calendar.MINUTE);
        }
    }
    
    @Override
    public String toString(){
        return getShortDesc();
    }

    @Override
    public void setId(int id) {
        this.id = id;
    }

    @Override
    public int getId() {
        return this.id;
    }

    /**
     * Vrací kontejner, který udržuje aktuální odpovědi vložené pomocí addReply.
     * @return Kontejner s aktuálními odpověďmi.
     */
    @Override
    public Container getContainer() {
        return container;
    }
    
    
    
    /**
     * Vytvoří obsah kontejneru. Neaktualizuje starý kontejner, ale vytváří nový, který bude odteď vracet metoda getContainer. Metoda by se měla volat ze Swing vlákna.
     */
    private void setupContainer(){
        container = new JPanel();
        synchronized(this){
            int yesCount = 0;
            int noCount = 0;
            for(Reply r:replies.values()){
                if(Reply.Yes.equals(r)){
                    yesCount++;
                }
                if(Reply.No.equals(r)){
                    noCount++;
                }
            }
            yesCounter = new JLabelCounter(yesCount);
            noCounter = new JLabelCounter(noCount);
        }
        JTable table = new JTable(tableModel);
        table.setPreferredSize(new Dimension(0, 200));
        container.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0; c.gridy = 0; c.gridwidth = 2; c.insets = new Insets(10, 10, 10, 10);
        c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.HORIZONTAL;
        container.add(table, c);
        c.gridy = 1; c.gridwidth = 1; c.insets = new Insets(0, 10, 0, 0);
        c.fill = GridBagConstraints.NONE;
        container.add(new JLabel("Všech odpovědí "+Reply.Yes+": "), c);
        c.gridx = 1; c.weightx = 1;
        container.add(yesCounter, c);
        c.gridx = 0; c.gridy = 2; c.weightx = 0; c.weighty = 1;
        container.add(new JLabel("Všech odpovědí "+Reply.No+": "), c);
        c.gridx = 1; c.weightx = 1; c.weighty = 1;
        container.add(noCounter, c);
    }
    
    
    private String message = null;
    private int id = -1;
    private JPanel container = new JPanel();
    private JLabelCounter yesCounter;
    private JLabelCounter noCounter;
    private Map<Connection, Reply> replies = new HashMap<>();
    private ReadOnlyTableModel tableModel = new ReadOnlyTableModel();
    private Calendar date = Calendar.getInstance();
            
    private static enum Reply{
        Yes{
            @Override
            public String toString(){
                return "Ano";
            }
        }
        , No{
            @Override
            public String toString(){
                return "Ne";
            }
        };
    }
}
